﻿using AutoMapper;
using DataBase.DBmodels;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media;
using Util;

namespace DataBase.Utils
{
    public class MyDbContext : DbContext
    {
        private static MyDbContext _instance = null;
        private static MyDbContext _instance2 = null;
        private static readonly object Padlock = new object();
        private static readonly object Padlock2 = new object();

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            // 配置数据库连接字符串和提供程序
            optionsBuilder.UseMySQL(ConnnectUtl.DbConnectStr+";SslMode=None;allowPublickeyRetrieval=true");
        }

        public DbSet<User> Users { get; set; }

        //public DbSet<UserDTO> UserDTOs { get; set; }
        public DbSet<GreenXi.Model.RolePermission> RolePermissions { get; set; }
        public DbSet<GreenXi.Model.UserRoleRelation> UserRoleRelations { get; set; }

        public DbSet<Decision> Decisions { get; set; }

        public DbSet<DecisionType> DecisionType { get; set; }
        public DbSet<Settings> Settings { get; set; }
        public DbSet<Craft> Craft { get; set; }
        public DbSet<ProductionData> ProductionData { get; set; }
        public DbSet<Electricity> Electricity{ get; set; }
        public DbSet<ControlLog> ControlLog { get; set; }

        public DbSet<Region> Regions { get; set; }
        public DbSet<Gateway> Gateways { get; set; }

        public DbSet<timeslot> timeslots { get; set; }

        public DbSet<productiondatalog> productiondatalogs { get; set; }
        
        #region 通用类
        // 通用增删改查方法
        /// <summary>
        /// 通用的按照 ID 查询实体方法
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="id">实体的 ID</param>
        /// <returns>查询到的实体对象</returns>
        public async Task<T> GetByIdAsync<T>(int id)
            where T : class
        {
            return await Set<T>().FindAsync(id);
        }

        /// <summary>
        /// 通用的查询所有实体方法
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <returns>所有实体的列表</returns>
        public async Task<List<T>> GetAllAsync<T>()
            where T : class
        {
            return await Set<T>().ToListAsync();
        }

        /// <summary>
        /// 通用的添加单个实体方法
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="entity">要添加的实体对象</param>
        public async Task AddAsync<T>(T entity)
            where T : class
        {
            await Set<T>().AddAsync(entity);
            await SaveChangesAsync();
        }

        /// <summary>
        /// 通用的更新单个实体方法
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="entity">要更新的实体对象</param>
        public async Task UpdateAsync<T>(T entity)
            where T : class
        {
            Set<T>().Update(entity);
            await SaveChangesAsync();
        }

        /// <summary>
        /// 通用的删除单个实体方法
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="entity">要删除的实体对象</param>
        public async Task DeleteAsync<T>(T entity)
            where T : class
        {
            //按快了会闪退
            Set<T>()
                .Remove(entity);
            await SaveChangesAsync();
        }

        /// <summary>
        /// 批量添加实体对象到数据库
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="entities">要添加的实体对象列表</param>
        public async Task AddRangeAsync<T>(IEnumerable<T> entities)
            where T : class
        {
            await Set<T>().AddRangeAsync(entities);
            await SaveChangesAsync();
        }

        #endregion

        #region 安全相关
        /// <summary>
        /// 双锁，多线程安全的单例模式
        /// </summary>
        public static MyDbContext Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (Padlock)
                    {
                        if (_instance == null)
                        {
                            _instance = new MyDbContext();
                        }
                    }
                }

                return _instance;
            }
        }

        public static MyDbContext Instance2
        {
            get
            {
                if (_instance2 == null)
                {
                    lock (Padlock2)
                    {
                        if (_instance2 == null)
                        {
                            _instance2 = new MyDbContext();
                        }
                    }
                }

                return _instance2;
            }
        }
        #endregion

        #region Decision

        /// <summary>
        /// 获取所有判断框根据
        /// </summary>
        /// <returns></returns>
        public List<Decision> GetDecision(string PresssId)
        {
            using MyDbContext myDbContext = new();
            var Decisions = myDbContext.Decisions.Where(x => x.PressId == PresssId);
            var aa = Decisions.Count();
            if (Decisions!=null&&Decisions.Count() != 0)
            {
                return Decisions.ToList();
            }
            else
            {
                return new List<Decision>();
            }
        }
        public List<Decision> GetDecisionByFuncName(string funcName, string pressId)
        {
            using MyDbContext myDbContext = new();
            var Decisions = myDbContext.Decisions.Where(x => x.ParentId == funcName && x.PressId == pressId);
            try
            {
                return Decisions.ToList();
            }
            catch (Exception ex)
            {
                return new List<Decision>();
            }
        }
     

        public List<Decision> GetDecisionById(int id)
        {
            using MyDbContext myDbContext = new();
            var Decisions = myDbContext.Decisions.Where(x => x.ID == id);
            var aa = Decisions.Count();
            if (Decisions.Count() != 0)
            {
                return Decisions.ToList();
            }
            else
            {
                return new List<Decision>();
            }
        }

        /// <summary>
        /// 删除判断框
        /// </summary>
        /// <returns></returns>
        public void DecisionDel(Decision decision)
        {
            using MyDbContext myDbContext = new();
            var Entity = myDbContext.Decisions.FirstOrDefault(x => x.ID == decision.ID);
            if (Entity != null)
            {
                myDbContext.Decisions.Remove(Entity);
            }
            myDbContext.SaveChanges();
        }

        public void DecisionAdd(Decision decision)
        {
            using MyDbContext myDbContext = new();
            myDbContext.Decisions.Add(decision);
            myDbContext.SaveChanges();
        }

        public void DecisionUpdate(Decision Decision)
        {
            using MyDbContext myDbContext = new();
            var decisions = myDbContext.Decisions.FirstOrDefault(x => x.ID == Decision.ID);
            if (decisions != null)
            {
                decisions.Image = Decision.Image;
                decisions.Type = Decision.Type;
                decisions.X1 = Decision.X1;
                decisions.X2 = Decision.X2;
                decisions.Y1 = Decision.Y1;
                decisions.Y2 = Decision.Y2;
                decisions.PressId = Decision.PressId;
                decisions.ParentId = Decision.ParentId ?? "未绑定";
                myDbContext.SaveChanges();
            }
            else
            {
                myDbContext.Decisions.Add(decisions);
                myDbContext.SaveChanges();
            }
        }
        #endregion

        #region DecisionType 判断框类型
        /// <summary>
        /// 获取所有判断框类型
        /// </summary>
        /// <returns></returns>
        public List<DecisionType> GetDecisionType()
        {
            using MyDbContext myDbContext = new();
            List<DecisionType> decisiontype = new List<DecisionType>();
            decisiontype = myDbContext.DecisionType.ToList();
            return decisiontype;
        }

        public DecisionType GetDecisionType(string name)
        {
            using MyDbContext myDbContext = new();
            DecisionType decisiontype = new DecisionType();
            decisiontype = myDbContext.DecisionType.Where(x => x.Name == name).FirstOrDefault();
            return decisiontype;
        }
        #endregion

        #region Craft
        /// <summary>
        /// 根据压机ID PressId 获取判断框类型
        /// </summary>

           public List<Region> GetRegion()
        {
            using MyDbContext myDbContext = new();
            return myDbContext.Regions.ToList();
        }

        public List<Gateway> GetGateway()
        {
            using MyDbContext myDbContext = new();
            return myDbContext.Gateways.ToList();
        }
        public void UpdateGateway(Gateway region)
        {
            using MyDbContext myDbContext = new();
            myDbContext.Gateways.Update(region);
            myDbContext.SaveChanges();
        }
        public void UpdateRegion(Region region)
        {
            using MyDbContext myDbContext = new();
            myDbContext.Regions.Update(region);
            myDbContext.SaveChanges();
        }



        public List<timeslot> GetTimeslot()
        {
            using MyDbContext myDbContext = new();
            return myDbContext.timeslots.ToList();
        }


        public void UpdateTimeslot(timeslot timeslot)
        {
            using MyDbContext myDbContext = new();
            myDbContext.timeslots.Update(timeslot);
            myDbContext.SaveChanges();
        }

        /// <summary>
        /// 根据压机Name获取类型
        /// </summary>





        public void AddCraftList(List<Craft> craft)
        {
            using MyDbContext myDbContext = new MyDbContext();
            myDbContext.Craft.AddRange(craft);
            myDbContext.SaveChanges();
        }

        public void UpdateCraft(Craft craft)
        {
            using MyDbContext myDbContext = new();
            myDbContext.Craft.Update(craft);
            myDbContext.SaveChanges();
        }

        /// <summary>
        /// 根据压机Type类型id获取行程
        /// </summary>
        public List<Craft> GetCraftByType(int type)
        {
            MyDbContext myDbContext = new();
            return myDbContext.Craft.Where(x => x.Type == type).OrderBy(x => x.Id).ToList();
        }
        public static List<CraftView> GetCraftViewByType(int type)
        {
            MyDbContext myDbContext = new();
            List<Craft> aa=new List<Craft>();
            if (type == 0)
            {
               aa = myDbContext.Craft.OrderBy(x => x.Id).ToList();
            }else if (type == 5)
            {
                aa = myDbContext.Craft.Where(x => x.Type ==1||x.Type==3).OrderBy(x => x.Id).ToList();
            }
            else
            {
                aa = myDbContext.Craft.Where(x => x.Type == type).OrderBy(x => x.Id).ToList();
            }
           

            // 配置 AutoMapper
            var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<Craft, CraftView>();
            });

            IMapper mapper = config.CreateMapper();

            // 使用 AutoMapper 进行转换
            List<CraftView> craftViewList = mapper.Map<List<CraftView>>(aa);
            if (craftViewList == null)
            {
                craftViewList=new List<CraftView>();
            }
            return craftViewList;
        }

        public void CraftDel(Craft craft)
        {
            using MyDbContext myDbContext = new();
            var Entity = myDbContext.Craft.FirstOrDefault(x => x.Id == craft.Id);
            myDbContext.Craft.Remove(Entity);
            myDbContext.SaveChanges();
        }



        #endregion

        #region Settings
        public Settings? GetValueByKey(string name)
        {
            using MyDbContext myDbContext = new();
            return myDbContext.Settings.Where(x => x.Key == name).FirstOrDefault();
        }

        public Result SetValueByKey(string name, string value)
        {
            Result result = new Result();
            using MyDbContext myDbContext = new();
            var entry = myDbContext.Settings.Where(x => x.Key == name).FirstOrDefault();
            if (entry != null)
            {
                entry.Value = value;
                myDbContext.SaveChanges();
                result.Code = 200;
                result.Message = "OK";
                return result;
            }
            else
            {
                result.Code = 404;
                result.Message = "未找到数据";
                return result;
            }
        }

        /// <summary>
        /// 从数据库获取配置列表
        /// </summary>
        /// <typeparam name="T">要获取的集合的类型</typeparam>
        /// <param name="settingName">数据库中该配置的名称</param>
        /// <param name="options">数据库中该配置的默认选项</param>
        /// <param name="desc">数据库中该配置的备注</param>
        /// <returns>数据库中对应配置名称的选项列表</returns>
        public static ObservableCollection<T> GetSettingListByDb<T>(string settingName, T defeultVal, string options, string desc)
        {
            using MyDbContext myDbContext = new();
            var setting = myDbContext.Settings.FirstOrDefault(x => x.Key == settingName);

            if (setting == null)
            {
                setting = new Settings
                {
                    Key = settingName,
                    Value = defeultVal.ToString(),
                    Option = options,
                    Describe = desc
                };

                myDbContext.Settings.Add(setting);
                myDbContext.SaveChanges();
            }

            if (!string.IsNullOrEmpty(setting.Option))
            {
                string[] values = setting.Option.Split(',');
                ObservableCollection<T> collection = new(values.Select(x => (T)Convert.ChangeType(x, typeof(T))));
                return collection;
            }
            else
            {
                return new ObservableCollection<T>();
            }
        }

        /// <summary>
        /// 从数据库获取配置的值
        /// </summary>
        /// <typeparam name="T">要获取的集合的类型</typeparam>
        /// <param name="settingName">数据库中该配置的名称</param>
        /// <param name="defeultVal">数据库中该配置的默认值</param>
        /// <param name="desc">数据库中该配置的备注</param>
        /// <returns>数据库中对应配置名称的值</returns>
        public static T GetSettingByDb<T>(string settingName, T defeultVal, string desc)
        {
            var setting = Instance.Settings.FirstOrDefault(x => x.Key == settingName);

            if (setting == null)
            {
                setting = new Settings
                {
                    Key = settingName,
                    Value = defeultVal.ToString(),
                    Describe = desc
                };

                Instance.Settings.Add(setting);
                Instance.SaveChanges();
            }

            if (typeof(T) == typeof(TimeSpan))
            {
                // T 是 TimeSpan 类型
                TimeSpan timeSpanValue = TimeSpan.Parse(setting.Value);
                return (T)Convert.ChangeType(timeSpanValue, typeof(T));
            }
            else
            {
                return (T)Convert.ChangeType(setting.Value, typeof(T));
            }
        }

        public static void SetSettingDbInfo<T>(string settingName, T value)
        {
            using MyDbContext myDbContext = new();
            var setting = myDbContext.Settings.FirstOrDefault(x => x.Key == settingName);
            if (setting != null)
            {
                setting.Value = value.ToString();
                myDbContext.Settings.Update(setting);
                myDbContext.SaveChanges();
            }
        }

        public static T GetSettingByDb<T>(string name)
        {
            using MyDbContext myDbContext = new();
            var obj = myDbContext.Settings.FirstOrDefault(x => x.Key == name);
            if (obj != null)
            {
                var value = obj.Value;
                T settingValue = (T)Convert.ChangeType(value, typeof(T));
                return settingValue;
            }
            else
            {
                return (T)Convert.ChangeType("0", typeof(T));
            }
        }
        #endregion

        

        #region GetElectricityData
        /// <summary>
        /// 查询所有数据
        /// <paramref name="Code">productiondata Id</paramref>
        /// </summary>
        public List<Electricity> GetElectricityData(int CraftId,DateTime startTime,DateTime endTime)
        {
            using MyDbContext myDbContext = new();
            var list = myDbContext.Electricity.Where(x => x.CraftId == CraftId && x.CreateTime.Value>= startTime&& x.CreateTime.Value <= endTime)
            .ToList();
            return list;


        }
        public List<Electricity> GetElectricityDataAll(int CraftId)
        {
            using MyDbContext myDbContext = new();
            var list = myDbContext.Electricity.Where(x => x.CraftId == CraftId )
                .ToList();
            return list;
        }

        public List<ProductionData> GetProductionSelect(string Sn, string ? CylinderNo,int Type, DateTime? StartTime, DateTime? EndTime)
        {
            using MyDbContext myDbContext = new();
            var list = myDbContext.ProductionData.Where(x => x.Id > 0);
            list = list.OrderByDescending(x => x.Id);
            if (!string.IsNullOrEmpty(Sn) && Sn != "0")
            {
                list = list.Where(x => x.Sn == Sn).OrderByDescending(x => x.Id);
            }
            if (!string.IsNullOrEmpty(CylinderNo) &&CylinderNo != "0")
            {
                list = list.Where(x => CylinderNo.Contains(x.CylinderNo.ToString())).OrderByDescending(x => x.Id);
            }
            if (StartTime != null && StartTime.ToString() != "0001/1/1 0:00:00")
            {
                list = list.Where(x => x.CreateTime >= StartTime).OrderByDescending(x => x.Id);
            }
            if (EndTime != null && EndTime.ToString() != "0001/1/1 0:00:00")
            {
                list = list.Where(x => x.CreateTime <= EndTime).OrderByDescending(x => x.Id);
            }
            if (Type == 6)
            {
                list = list.Where(x => x.Type == 1|| x.Type==3).OrderByDescending(x => x.Id);
            }
            else
            {
                list = list.Where(x => x.Type == Type);
            }

           


            return list.ToList();
        }

        public ProductionData ProductionDataAdd(ProductionData data)
        {
            MyDbContext myDbContext = new();
            myDbContext.ProductionData.Add(data);
            myDbContext.SaveChanges();
            return data;
        }
        #endregion



        #region ControlLog
        public static void SetLog(
            string logInfo,
            string Type = ""
        )
        {
            using (MyDbContext myDbContext = new())
            {
                
                ControlLog controlLog =
                    new()
                    {
                        LogInfo = logInfo,
                        CreateTime = DateTime.Now,
                        Type= Type,
                    };
                myDbContext.ControlLog.Add(controlLog);
                myDbContext.SaveChanges();
            }
        }
        #endregion
    }
}
